// 来自网络题解
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using Q =
    tuple<int, int, int, int>; // 定义查询类型：左边界、右边界、容量、查询索引

// 全局变量定义
vector<int> w, v;      // w: 物品重量数组, v: 物品价值数组
vector<Q> qs;          // 存储所有查询
vector<ll> ans;        // 存储每个查询的答案
vector<vector<ll>> dp; // 动态规划数组，dp[i][j]表示从位置i开始的最大价值
int m;                 // 背包最大容量

// 辅助函数：更新最大值
inline void chmax(ll &a, ll b) {
  if (a < b)
    a = b;
}

// 分治算法解决区间背包问题
// l: 当前处理区间的左边界
// r: 当前处理区间的右边界
void solve(int l, int r) {
  int k = (l + r) / 2; // 计算中点

  // 初始化中点位置的dp数组
  dp[k] = vector<ll>(m + 1);

  // 从中点向左处理：计算从每个位置到中点的背包状态
  for (int i = k - 1; i >= l; --i) {
    dp[i] = dp[i + 1]; // 继承右边位置的dp状态
    // 进行背包更新：从后往前更新避免重复计算
    for (int j = m - w[i]; j >= 0; --j) {
      chmax(dp[i][j + w[i]], dp[i][j] + v[i]);
      // 相当于： dp[i][j + w[i]] = max(dp[i][j + w[i]], dp[i][j] + v[i]);
    }
  }

  // 从中点向右处理：计算从中点到每个位置的背包状态
  for (int i = k; i < r; ++i) {
    dp[i + 1] = dp[i]; // 继承左边位置的dp状态
    // 进行背包更新
    for (int j = m - w[i]; j >= 0; --j) {
      chmax(dp[i + 1][j + w[i]], dp[i + 1][j] + v[i]);
      // 相当于  dp[i + 1][j + w[i]] = max(dp[i + 1][j + w[i]], dp[i + 1][j] +
      // v[i]);
    }
  }

  // 分类处理查询
  vector<Q> ql, qr; // 分别存储左半区间和右半区间的查询
  for (auto [nl, nr, c, qi] : qs) {
    if (nr < k) // 查询完全在左半区间
      ql.emplace_back(nl, nr, c, qi);
    else if (nl > k) // 查询完全在右半区间
      qr.emplace_back(nl, nr, c, qi);
    else { // 查询跨越中点，可以立即计算答案
      ll now = 0;
      // 枚举分割点：左半部分使用j容量，右半部分使用c-j容量
      for (int j = 0; j <= c; ++j)
        chmax(now, dp[nl][j] + dp[nr][c - j]);
      // 相当于： now = max(now, dp[nl][j] + dp[nr][c - j]);
      ans[qi] = now; // 记录答案
    }
  }

  // 递归处理左右子区间
  if (ql.size())
    solve(l, k); // 处理左半区间的查询
  if (qr.size())
    solve(k, r); // 处理右半区间的查询
}

int main() {
  int n;
  cin >> n; // 输入物品数量

  // 初始化物品信息
  w.resize(n);
  v.resize(n);
  for (int i = 0; i < n; ++i)
    cin >> w[i] >> v[i]; // 输入每个物品的重量和价值

  int q;
  cin >> q; // 输入查询数量
  qs.resize(q);
  for (int qi = 0; qi < q; ++qi) {
    int l, r, c;
    cin >> l >> r >> c;               // 输入查询：区间[l, r]和容量c
    --l;                              // 转换为0-based索引
    qs[qi] = make_tuple(l, r, c, qi); // 存储查询信息
  }

  // 初始化答案数组和dp数组
  ans.resize(q);
  m = 500; // 设置最大容量为500
  dp.resize(n + 1, vector<ll>(m + 1));

  // 调用分治算法解决所有查询
  solve(0, n);

  // 输出所有查询的答案
  for (int qi = 0; qi < q; ++qi)
    cout << ans[qi] << '\n';

  return 0;
}
// 改造自：https://www.cnblogs.com/Melville/p/19126506